package com.lx.idea.common.util;

import cn.caict.tool.SignXmlTool;
import cn.caict.tool.TarGzUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.XmlUtil;
import com.lx.idea.report.model.RootRealTimeInfo;
import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Slf4j
public class XmlUtils {

    /**
     * 校验xml格式是否正确
     *
     * @param xsdFile
     * @param xmlFile
     * @return
     */
    public static boolean validateXMLSchema(File xsdFile, File xmlFile) {
        log.info("校验文件 =>{}   <>    XML文件 => {}",xsdFile.getName(),xmlFile.getName());
        try {
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema schema = factory.newSchema(xsdFile);
            Validator validator = schema.newValidator();
            validator.validate(new StreamSource(xmlFile));
        } catch (IOException | SAXException e) {
            log.error("xml文件格式校验异常，文件名：{}", xmlFile.getName(), e);
            return false;
        }
        return true;
    }

    /**
     * xml文件签名
     * 其中“秘钥字符串”由顶级审核机构信息并通过时，邮件发给客户，并由客户自行保存
     *
     * @param filePath      签名文件路径
     * @param privateKeyStr 签名秘钥
     */
    public static void signXml(String filePath, String privateKeyStr) {
        try {
            SignXmlTool.signXml(filePath, privateKeyStr);
        } catch (Exception e) {
            log.error("xml签名异常，文件路径：{}", filePath, e);
        }
    }

    /**
     * 保存xml
     *
     * @param document
     */
    public static void writeXml(Document document, String filePath, String fileName) {
        XmlUtil.toStr(document);
        if (!FileUtil.exist(filePath)) {
            FileUtil.mkdir(filePath);
        }
        FileOutputStream fileOutputStream = null;
        String path = filePath + fileName;
        try {
            fileOutputStream = new FileOutputStream(new File(path));
        } catch (FileNotFoundException e) {
            log.error("xml创建异常，文件路径：{}", filePath, e);
        }
        XmlUtil.write(document, fileOutputStream, "UTF-8", 2);
    }

    /**
     * 打包成tar.gz
     *
     * @param outPath 输出文件路径
     * @param filePath 需要打包的文件路径
     */
    public static void packetXml(String outPath, List<String> filePath) {
        List<File> resourceList = new ArrayList<>();
        try {
            for (String s : filePath) {
                File file01 = new File(s);
                resourceList.add(file01);
            }
            TarGzUtil.packet(resourceList, outPath);
        } catch (Exception e) {
            log.error("xml打包异常，文件路径：{}，文件输出路径：{}", filePath.toString(), outPath, e);
        }
    }

    public void creatXmlDemo() {
        Document document = XmlUtil.createXml();
        Element root = document.createElement("rsmi:regSrvMainInfo");
        root.setAttribute("xmlns:rsmi", "urn:ietf:params:xml:ns:regsvrmaininfo-1.0");
        root.setAttribute("xmlns:bt", "urn:ietf:params:xml:ns:basetype-1.0");
        root.setAttribute("xmlns:rmci", "urn:ietf:params:xml:ns:regmancominfo-1.0");
        Element regManComInfo = document.createElement("rsmi:regManComInfo");
        Element regServerType = document.createElement("rmci:regServerType");
        Element servName = document.createElement("bt:servName");
        Element gnrlId = document.createElement("bt:gnrlId");
        servName.setTextContent("信通院");
        gnrlId.setTextContent("2631614400000001");
        regServerType.appendChild(servName);
        regServerType.appendChild(gnrlId);
        regManComInfo.appendChild(regServerType);
        root.appendChild(regManComInfo);
        document.appendChild(root);
        writeXml(document,"","");
    }
    public static void createXmlDemo2(RootRealTimeInfo e,String dir,String fileName) throws IllegalAccessException {
        Document document = XmlUtil.createXml();
        Element root = document.createElement("rrti:rootReaTimInfo");
        root.setAttribute("xmlns:rrti", "urn:ietf:params:xml:ns:rootreatiminfo-1.0");
        root.setAttribute("xmlns:rsrti", "urn:ietf:params:xml:ns:regsrvreatiminfo-1.0");
        root.setAttribute("xmlns:rmci", "urn:ietf:params:xml:ns:rootservcominfo-1.0");
        root.setAttribute("xmlns:bt", "urn:ietf:params:xml:ns:basetype-1.0");

        Element regManComInfo = document.createElement("rrti:rootComInfo");
        Element pubKeySign = document.createElement("rrti:pubKeySign");

        Element regServerType = document.createElement("rmci:regServerType");
        Element servName = document.createElement("bt:servName");
        Element gnrlId = document.createElement("bt:gnrlId");
        servName.setTextContent("信通院");
        gnrlId.setTextContent("2631614400000001");
        regServerType.appendChild(servName);
        regServerType.appendChild(gnrlId);

        Element idType = document.createElement("rmci:idType");
        Element dataCrtTime = document.createElement("rmci:dataCrtTime");
        Element operType = document.createElement("rmci:operType");
        Element transId = document.createElement("rmci:transId");

        regManComInfo.appendChild(regServerType);
        regManComInfo.appendChild(idType);
        regManComInfo.appendChild(dataCrtTime);
        regManComInfo.appendChild(operType);
        regManComInfo.appendChild(transId);

        Element data = document.createElement("rrti:data");
        Field[] fields = e.getClass().getDeclaredFields();
        for(int i=0; i<fields.length; i++){
            Field f = fields[i];
            f.setAccessible(true);
//            System.out.println("属性名:" + f.getName() + " 属性值:" + f.get(e));
            Element el = document.createElement("rsrti:"+f.getName());
            Object obj = f.get(e);
            el.setTextContent(null == obj ? "": obj.toString());
            data.appendChild(el);
        }
        root.appendChild(pubKeySign);
        root.appendChild(regManComInfo);
        root.appendChild(data);
        document.appendChild(root);
        writeXml(document,dir+"/xml/",fileName);
    }

    public static void main(String[] args) throws Exception {
        String dir = "E:/work2/ma-identity-resolution/ma-analysis/src/main/resources/template/";
        RootRealTimeInfo rootRealTimeInfo = new RootRealTimeInfo();
        String fileName = rootRealTimeInfo.fileName();
        createXmlDemo2(rootRealTimeInfo,dir,fileName);


        String privateKeyStr = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCnBs196+qSJZ1r+Wu13WGivGP3JdgUY0T/bTVdZpAN5lcSQb8IPcrte2Jt1mow2xAWHEygj+ZTFNk1oG+q+ftY0YMzXSQTEMTS5T0dVTPfIwLm2Q0sM1sjTK2liIk9VJSGMlaEco6UpjhNnZn29K52Pd0QfezW/PKQ/TtuSIjeZ96apZaD4HKQNu6uZ9hIgpoAV3Ej8MQguOnd9DqvFos4PUTsA5pZiOBsruYFkobEAEm6g9hBifqU3oJvnat/zhXB+ZnaBNHZvRAvAqHRarnuj6zcSWyMFVhg9ZcuslgFKces3flBCxisizQi+uEN0ymu/WVGyFYEHlNzvL8O9/zHAgMBAAECggEBAI6gXXtIqE7SNgIMw7BR8dzAGHDkbQbD2hhvjiFKwnpMFlAtuk30TkPKl7uJW7aKacsnsTtuhdSuOej0LkcHHl2y0uFaiMKLEDeyryRMLHY/dGviLsBuvkV/ZcyzsdWgUw/hDkYdeKlw4yVMDjx2pj+sBgjeLw9KgmvTAhvjbpTTIrucn/g1FB3mzwOgxH5W0mYlW8upTJ/Uq1Vcx2NRxOmPLYCO9p2lXQ7tKO6KkTC0+U01udpdKmj9pW9HW34PMbpwr+LBL3UFRjqYpwemxIEABM9PYSLlhdzUDHg+ugF+qhQaD09JMajjFanzrl+PQizrepbAA4XA1ibPZn2OZVECgYEA7yTrO0yAcJo61/lZ5S5kx4UHPC3Ef+UVQbuWWf0AHy3Zp5nZREZD04DfnLwI1rkS+RnjBfkYTjFc2jlzok58/YwSVXxtMZ29MtUE2JgNz4Ae09yb5GoFPtgPg7Sm9eVpewmY9oNprdLruQHAMdGVfGCJ2gtWaqP+bpwec0gqcA8CgYEAssyass3Yx+SUS3eK+AO1mop3CidgEiWOm+W+3cpZiY2uFhjJMUCy3bh6kpp1JSELMfpQlKfTaYJvH8Bgq2xzvzwN2wqaLpvQBPLVXQJsupodgtw+SJ2URmiUpRk0/vVD4qmb7+bNiJxw3DfAk8O/OzD+U2i9C12du6DJVMB478kCgYEA6mO7EzHWKYdg6VICY/hm2o9uGfOZxujXPsgHg0fQGL8tt3G5W4uq6uBDSzGZUCuxhulyc+ZDhlAne9QXnBtlsnTZe2Qq+hhq2imjSE8wKhKfJHPzb5ribUgDXMlxY01pZyhu/h6rM62pUHmA0NNkurU8J7Q5DOiTdgIabk9rGM0CgYA0z2P93fjiiawXYjakrIvOGomwcRLaKUem2kP2xFaP304E7ss2BfMOs/dYJ9Dj54+j8lgsoCk8Z68kxLCI0V6apEU/ZjFGBPV7ELJeZ2Hv96cxyJWI4yoxZaBJ51kU2SJ05z3MrPIWIIbhNIJn4pAwDnd/8Vas7bix+3qb0sGlqQKBgA58kRVmFIB/eaR7DlX5bum7I/QdrsNi91tGVMeg6ralNEXuWB+6JJ5IQ/MeNx927P4CLhM6ccIPAsdMkMc7g+TyuasCHLTj32RCJdDJlfBS1/VLZFDMZH0/bR5lreE3ib7XnHArrLH5y+/YSn/RAjd/ZEw9Ln2ZsFMnhWI/EU5Z";
        String localPath = dir+"xml/"+fileName;
        XmlUtils.signXml(localPath, privateKeyStr);
        String outPath = dir+"tar/"+fileName+".tar.gz";
        List<String> filePath = Arrays.asList(localPath, localPath);
        XmlUtils.packetXml(outPath, filePath);


    }
}
